const express = require('express');
const session = require('express-session');
const multer = require('multer');
const bcrypt = require('bcryptjs');
const path = require('path');
const fs = require('fs');

const app = express();
const PORT = process.env.PORT || 3000;

// 中间件配置
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// CORS中间件，解决跨域问题
app.use((req, res, next) => {
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
    res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
    
    // 处理预检请求
    if (req.method === 'OPTIONS') {
        res.sendStatus(200);
    } else {
        next();
    }
});

app.use(express.static('public'));
app.use('/uploads', express.static('uploads'));

// 会话配置
app.use(session({
    secret: 'your-secret-key',
    resave: false,
    saveUninitialized: false,
    cookie: { secure: false }
}));

// 文件上传配置
const storage = multer.diskStorage({
    destination: function (req, file, cb) {
        const uploadDir = 'uploads';
        if (!fs.existsSync(uploadDir)) {
            fs.mkdirSync(uploadDir);
        }
        cb(null, uploadDir);
    },
    filename: function (req, file, cb) {
        const timestamp = Date.now();
        cb(null, `${timestamp}-${file.originalname}`);
    }
});

// 配置multer，确保正确处理文件名编码
const upload = multer({ 
    storage: storage,
    fileFilter: function (req, file, cb) {
        // 确保文件名编码正确
        if (file.originalname) {
            file.originalname = Buffer.from(file.originalname, 'latin1').toString('utf8');
        }
        cb(null, true);
    }
});

// 从JSON文件读取用户数据
function loadUsers() {
    try {
        const usersPath = path.join(__dirname, 'data', 'users.json');
        if (fs.existsSync(usersPath)) {
            const usersData = fs.readFileSync(usersPath, 'utf8');
            return JSON.parse(usersData);
        } else {
            // 如果文件不存在，创建默认用户
            const defaultUsers = [
                {
                    username: 'admin',
                    password: '$2a$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi' // password
                }
            ];
            // 确保data目录存在
            const dataDir = path.join(__dirname, 'data');
            if (!fs.existsSync(dataDir)) {
                fs.mkdirSync(dataDir);
            }
            fs.writeFileSync(usersPath, JSON.stringify(defaultUsers, null, 2));
            return defaultUsers;
        }
    } catch (error) {
        console.error('加载用户数据失败:', error);
        // 返回默认用户
        return [
            {
                username: 'admin',
                password: '$2a$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi'
            }
        ];
    }
}

let users = loadUsers();

// 文件数据存储
let files = [];

// 扫描uploads目录，加载已存在的文件
function scanUploadsDirectory() {
    const uploadsDir = path.join(__dirname, 'uploads');
    if (fs.existsSync(uploadsDir)) {
        const fileList = fs.readdirSync(uploadsDir);
        fileList.forEach(filename => {
            // 检查是否已经存在于files数组中
            const existingFile = files.find(f => f.storedName === filename);
            if (!existingFile) {
                // 解析文件名获取时间戳和原始文件名
                const parts = filename.split('-');
                if (parts.length >= 2) {
                    const timestamp = parseInt(parts[0]);
                    const originalName = parts.slice(1).join('-');
                    
                    // 获取文件信息
                    const filePath = path.join(uploadsDir, filename);
                    const stats = fs.statSync(filePath);
                    
                    const fileInfo = {
                        id: timestamp,
                        filename: originalName,
                        originalFilename: originalName,
                        storedName: filename,
                        size: stats.size,
                        uploadTime: new Date(timestamp).toISOString(),
                        uploader: 'system' // 标记为系统扫描的文件
                    };
                    
                    files.push(fileInfo);
                }
            }
        });
    }
    console.log(`扫描完成，找到 ${files.length} 个文件`);
}

// 启动时扫描uploads目录
scanUploadsDirectory();

// 认证中间件
function requireAuth(req, res, next) {
    if (req.session.user) {
        next();
    } else {
        res.redirect('/login');
    }
}

// 路由
app.get('/', (req, res) => {
    res.sendFile(path.join(__dirname, 'public', 'index.html'));
});

app.get('/admin', requireAuth, (req, res) => {
    res.sendFile(path.join(__dirname, 'public', 'admin.html'));
});

app.get('/iframe', (req, res) => {
    res.sendFile(path.join(__dirname, 'public', 'iframe.html'));
});

app.get('/iframe-cors', (req, res) => {
    res.sendFile(path.join(__dirname, 'public', 'iframe-cors.html'));
});

app.get('/iframe-example', (req, res) => {
    res.sendFile(path.join(__dirname, 'public', 'iframe-example.html'));
});

app.get('/test', (req, res) => {
    res.sendFile(path.join(__dirname, 'public', 'test.html'));
});

app.get('/login', (req, res) => {
    if (req.session.user) {
        res.redirect('/');
    } else {
        res.sendFile(path.join(__dirname, 'public', 'login.html'));
    }
});

app.post('/login', async (req, res) => {
    const { username, password } = req.body;
    
    const user = users.find(u => u.username === username);
    if (user && await bcrypt.compare(password, user.password)) {
        req.session.user = { username: user.username };
        res.json({ success: true });
    } else {
        res.status(401).json({ success: false, message: '用户名或密码错误' });
    }
});

app.post('/logout', (req, res) => {
    req.session.destroy();
    res.json({ success: true });
});

// 修改密码
app.post('/change-password', requireAuth, async (req, res) => {
    try {
        const { currentPassword, newPassword } = req.body;
        
        if (!currentPassword || !newPassword) {
            return res.status(400).json({ 
                success: false, 
                message: '当前密码和新密码不能为空' 
            });
        }
        
        if (newPassword.length < 6) {
            return res.status(400).json({ 
                success: false, 
                message: '新密码长度不能少于6位' 
            });
        }
        
        // 验证当前密码
        const currentUser = users.find(u => u.username === req.session.user.username);
        if (!currentUser) {
            return res.status(404).json({ 
                success: false, 
                message: '用户不存在' 
            });
        }
        
        const isCurrentPasswordValid = await bcrypt.compare(currentPassword, currentUser.password);
        if (!isCurrentPasswordValid) {
            return res.status(400).json({ 
                success: false, 
                message: '当前密码错误' 
            });
        }
        
        // 加密新密码
        const hashedNewPassword = await bcrypt.hash(newPassword, 10);
        
        // 更新用户密码
        currentUser.password = hashedNewPassword;
        
        // 保存到JSON文件
        const usersPath = path.join(__dirname, 'data', 'users.json');
        fs.writeFileSync(usersPath, JSON.stringify(users, null, 2));
        
        res.json({ 
            success: true, 
            message: '密码修改成功' 
        });
        
    } catch (error) {
        console.error('修改密码失败:', error);
        res.status(500).json({ 
            success: false, 
            message: '修改密码失败，请稍后重试' 
        });
    }
});

// 文件上传
app.post('/upload', requireAuth, upload.single('file'), (req, res) => {
    if (!req.file) {
        return res.status(400).json({ success: false, message: '没有选择文件' });
    }
    
    const fileInfo = {
        id: Date.now(),
        filename: req.file.originalname,
        originalFilename: req.file.originalname,
        storedName: req.file.filename,
        size: req.file.size,
        uploadTime: new Date().toISOString(),
        uploader: req.session.user.username
    };
    
    files.push(fileInfo);
    res.json({ success: true, file: fileInfo });
});

// 获取文件列表（需要登录）
app.get('/files', requireAuth, (req, res) => {
    const { page = 1, limit = 10, search = '' } = req.query;
    const pageNum = parseInt(page);
    const limitNum = parseInt(limit);
    
    // 搜索过滤
    let filteredFiles = [...files]; // 创建副本避免修改原数组
    if (search && search.trim()) {
        filteredFiles = filteredFiles.filter(file => 
            file.filename.toLowerCase().includes(search.toLowerCase()) ||
            file.originalFilename.toLowerCase().includes(search.toLowerCase())
        );
    }
    
    // 按上传时间排序，最新文件在前
    filteredFiles.sort((a, b) => new Date(b.uploadTime) - new Date(a.uploadTime));
    
    // 分页
    const totalFiles = filteredFiles.length;
    const totalPages = Math.ceil(totalFiles / limitNum);
    const startIndex = (pageNum - 1) * limitNum;
    const endIndex = startIndex + limitNum;
    const paginatedFiles = filteredFiles.slice(startIndex, endIndex);
    
    res.json({ 
        files: paginatedFiles,
        pagination: {
            currentPage: pageNum,
            totalPages: totalPages,
            totalFiles: totalFiles,
            hasNext: pageNum < totalPages,
            hasPrev: pageNum > 1
        }
    });
});

// 手动扫描uploads目录（需要登录）
app.post('/scan-files', requireAuth, (req, res) => {
    try {
        scanUploadsDirectory();
        res.json({ success: true, message: `扫描完成，当前共有 ${files.length} 个文件` });
    } catch (error) {
        console.error('扫描文件失败:', error);
        res.status(500).json({ success: false, message: '扫描文件失败' });
    }
});

// 获取公开文件列表（不需要登录）
app.get('/public/files', (req, res) => {
    const { search = '', page = 1, limit = 10 } = req.query;
    const pageNum = parseInt(page);
    const limitNum = parseInt(limit);
    
    let filteredFiles = [...files]; // 创建副本避免修改原数组
    
    // 搜索过滤
    if (search.trim()) {
        filteredFiles = filteredFiles.filter(file => 
            file.filename.toLowerCase().includes(search.toLowerCase())
        );
    }
    
    // 按上传时间排序，最新文件在前
    filteredFiles.sort((a, b) => new Date(b.uploadTime) - new Date(a.uploadTime));
    
    // 分页
    const totalFiles = filteredFiles.length;
    const totalPages = Math.ceil(totalFiles / limitNum);
    const startIndex = (pageNum - 1) * limitNum;
    const endIndex = startIndex + limitNum;
    const paginatedFiles = filteredFiles.slice(startIndex, endIndex);
    
    const publicFiles = paginatedFiles.map(file => ({
        id: file.id,
        filename: file.filename,
        size: file.size,
        uploadTime: file.uploadTime
    }));
    
    res.json({ 
        files: publicFiles,
        pagination: {
            currentPage: pageNum,
            totalPages: totalPages,
            totalFiles: totalFiles,
            hasNext: pageNum < totalPages,
            hasPrev: pageNum > 1
        }
    });
});

// 文件下载（需要登录）
app.get('/download/:filename', requireAuth, (req, res) => {
    const filename = req.params.filename;
    const file = files.find(f => f.storedName === filename);
    
    if (!file) {
        return res.status(404).json({ success: false, message: '文件不存在' });
    }
    
    const filePath = path.join(__dirname, 'uploads', filename);
    res.download(filePath, file.filename);
});

// 公开文件下载（不需要登录）
app.get('/public/download/:fileId', (req, res) => {
    const fileId = parseInt(req.params.fileId);
    const file = files.find(f => f.id === fileId);
    
    if (!file) {
        return res.status(404).json({ success: false, message: '文件不存在' });
    }
    
    const filePath = path.join(__dirname, 'uploads', file.storedName);
    res.download(filePath, file.filename);
});

// 删除文件
app.delete('/files/:id', requireAuth, (req, res) => {
    const fileId = parseInt(req.params.id);
    const fileIndex = files.findIndex(f => f.id === fileId);
    
    if (fileIndex === -1) {
        return res.status(404).json({ success: false, message: '文件不存在' });
    }
    
    const file = files[fileIndex];
    const filePath = path.join(__dirname, 'uploads', file.storedName);
    
    // 删除物理文件
    if (fs.existsSync(filePath)) {
        fs.unlinkSync(filePath);
    }
    
    // 从列表中移除
    files.splice(fileIndex, 1);
    
    res.json({ success: true });
});

app.listen(PORT, () => {
    console.log(`服务器运行在 http://localhost:${PORT}`);
}); 



